package git

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var Accts = []string{"asset", "score", "invoice", "ams", "bill", "pay", "misc"}
var ProDir = "E:/work/Asiainfo/south-china/south-china-hnan"

//运行命令
//dir:运行目录
//命令名
//args 参数
func RunCommand(dir string, name string, args ...string) string {
	cmd := exec.Command(name, args...)
	cmd.Dir = dir
	msg, _ := cmd.CombinedOutput()
	_ = cmd.Run()
	return string(msg)
}

//运行git命令
func RunGitCommand(dir string, args ...string) string {
	return RunCommand(dir, "git", args...)
}

//运行git命令
func RunGitClone(url string, path string) string {
	b := strings.Index(filepath.Base(path), "-core") >= 0
	branch := "develop"
	if b {
		branch = "core-hnan-develop"
	}
	return RunCommand(filepath.Dir(path), "git", "clone", "-b", branch, url, path)
}

//branch1有branch2没有的
func DifferBranch(dir string, branch1 string, branch2 string) string {
	if strings.Index(branch1, "origin/") == -1 {
		branch1 = "origin/" + branch1
	}
	return RunGitCommand(dir, "log", branch1, "^"+branch2)
}

//是否合并到master分支
func IsInMaster(dir string, branch string) bool {
	msg := DifferBranch(dir, branch, "origin/master")
	return len(msg) == 0
}

//是否合并到core-master分支
func IsInCoreMaster(dir string, branch string) bool {
	msg := DifferBranch(dir, branch, "origin/core-hnan-master")
	return len(msg) == 0
}

//是否合并到develop分支
func IsInDevelop(dir string, branch string) bool {
	msg := DifferBranch(dir, branch, "origin/develop")
	return len(msg) == 0
}

//是否合并到core-develop分支
func IsInCoreDevelop(dir string, branch string) bool {
	msg := DifferBranch(dir, branch, "origin/core-hnan-develop")
	return len(msg) == 0
}

//获取最近版本号
func GetHisVersions(dir string, timeStr string) []string {
	var ret []string
	numStr := fmt.Sprintf("--after=%v", timeStr)
	msg := RunGitCommand(dir, "log", numStr, "--pretty=oneline")
	lines := strings.Split(msg, "\n")
	for _, line := range lines {
		v := strings.Split(line, " ")[0]
		if len(v) > 0 {
			ret = append(ret, v)
		}
	}
	return ret
}

//获取最近版本号
func GetHisVersionsByNum(dir string, num int) []string {
	var ret []string
	numStr := fmt.Sprintf("-%v", num)
	msg := RunGitCommand(dir, "log", "--pretty=oneline", numStr)
	lines := strings.Split(msg, "\n")
	for _, line := range lines {
		v := strings.Split(line, " ")[0]
		if len(v) > 0 {
			ret = append(ret, v)
		}
	}
	return ret
}

//获取指定版本文件内容
func GetFileInfoByVersion(dir string, v string, fileName string) string {
	numStr := fmt.Sprintf("%v:%v", v, fileName)
	return RunGitCommand(dir, "show", numStr)
}

//获取指定版本文件行
func GetVersionLines(dir string, fileName string, timeStr string) []string {
	command := RunGitPull(dir)
	fmt.Printf("更新updatelist:%v", command)
	var ret = GetVersionMapByTime(dir, fileName, timeStr)
	var retLines []string
	for k := range ret {
		retLines = append(retLines, k)
	}
	return retLines
}

func RunGitPull(dir string) string {
	return RunGitCommand(dir, "pull")
}

//获取指定版本文件行
func GetVersionMapByTime(dir string, fileName string, timeStr string) map[string]bool {
	versions := GetHisVersions(dir, timeStr)
	var ret = make(map[string]bool)
	for _, v := range versions {
		fileInfo := GetFileInfoByVersion(dir, v, fileName)
		lines := strings.Split(fileInfo, "\n")
		for _, line := range lines {
			all := strings.ReplaceAll(line, "\r", "")
			if len(all) > 0 {
				ret[all] = true
			}
		}
	}
	return ret
}

//获取指定版本文件行
func GetVersionMapByNum(dir string, fileName string, num int) map[string]bool {
	versions := GetHisVersionsByNum(dir, num)
	var ret = make(map[string]bool)
	for _, v := range versions {
		fileInfo := GetFileInfoByVersion(dir, v, fileName)
		lines := strings.Split(fileInfo, "\n")
		for _, line := range lines {
			all := strings.ReplaceAll(line, "\r", "")
			if len(all) > 0 {
				ret[all] = true
			}
		}
	}
	return ret
}

//获取指定版本文件行
func Compare(dir string, fileName string, timrStr string) string {
	lines := GetVersionLines(dir, fileName, timrStr)
	lastMap := GetVersionMapByNum(dir, fileName, 1)
	//更新代码
	PullAll()
	var inMasterBranchs []string
	var notInMasterBranchs []string
	for _, line := range lines {
		if strings.Index(line, "@") < 0 {
			continue
		}
		branch := strings.Split(line, "|")[0]
		project := strings.Split(line, "@")[1]
		if !IsAcctPro(project) {
			continue
		}
		checkDir := ProDir
		if strings.Index(project, "core") > 0 {
			checkDir += "/common/" + project
			master := IsInCoreMaster(checkDir, branch)
			if master {
				inMasterBranchs = append(inMasterBranchs, line)
			} else {
				notInMasterBranchs = append(notInMasterBranchs, line)
			}
		} else {
			checkDir += "/hnan/" + project
			master := IsInMaster(checkDir, branch)
			if master {
				inMasterBranchs = append(inMasterBranchs, line)
			} else {
				notInMasterBranchs = append(notInMasterBranchs, line)
			}

		}

	}
	out := "\n"
	out += "已经上master分支"
	for i := range inMasterBranchs {
		out += "\n"
		out += inMasterBranchs[i]
	}
	out += "\n"
	out += "没上master分支"
	for i := range notInMasterBranchs {
		out += "\n"
		out += notInMasterBranchs[i]
	}
	out += "\n"
	out += "没上master分支,也没在updateList列表"
	for i := range notInMasterBranchs {
		if !lastMap[notInMasterBranchs[i]] {
			out += "\n"
			out += notInMasterBranchs[i]
		}
	}
	out += "\n已经上master分支,还在updateList列表"
	for i := range inMasterBranchs {
		if lastMap[inMasterBranchs[i]] {
			out += "\n"
			out += inMasterBranchs[i]
		}
	}
	fmt.Printf(out)
	return out
}

func PullAll() {
	for _, pro := range Accts {
		msg := ""
		coreDir := ProDir + "/common/" + pro + "-core"
		if _, err := os.Stat(coreDir); err != nil {
			if _, err := os.Stat(filepath.Dir(coreDir)); err != nil {
				_ = os.MkdirAll(filepath.Dir(coreDir), os.ModePerm)
			}
			//_ = os.MkdirAll(coreDir, os.ModePerm)
			url := fmt.Sprintf("http://git.hnzx.com:18084/project/south-china/common/ams/%v-core.git", pro)
			msg = RunGitClone(url, coreDir)
		} else {
			msg = RunGitPull(coreDir)
		}
		fmt.Printf("更新%v-core,结果:%v", pro, msg)
		dir := ProDir + "/hnan/" + pro
		if _, err := os.Stat(dir); err != nil {
			if _, err := os.Stat(filepath.Dir(dir)); err != nil {
				_ = os.MkdirAll(filepath.Dir(dir), os.ModePerm)
			}
			//_ = os.MkdirAll(dir, os.ModePerm)
			url := fmt.Sprintf("http://git.hnzx.com:18084/project/south-china/hnan/ams/%v.git", pro)
			msg = RunGitClone(url, dir)
		} else {
			msg = RunGitPull(dir)
		}
		fmt.Printf("更新%v,结果:%v", pro, msg)
	}
}

func IsAcctPro(branch string) bool {
	for _, acct := range Accts {
		if branch == acct || branch == (acct+"-core") {
			return true
		}
	}
	return false
}
